package com.tangzx.ant;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.ArrayList;

import org.apache.tools.ant.BuildException;

import com.tangzx.builder.DefaultMixWordFactory;
import com.tangzx.builder.MovieMixer;
import com.tangzx.builder.abc.string.StringVo;
import com.tangzx.builder.context.AbcContext;
import com.tangzx.builder.decoder.ExcludeLib;
import com.tangzx.data.Swf;

public class ConfusionTask extends FSWD2Task {
	// 排除的关键字列表
	private String keyWordList;
	// 混淆关键字
	private String mixCharFile;
	private File logFile;
	private FileOutputStream logStream;
	private DefaultMixWordFactory mixWordFactory;
	
	private ArrayList<Swf> allExcludeLibList = new ArrayList<Swf>();
	private ArrayList<Swf> allSwf = new ArrayList<Swf>();
	private AbcContext abcContext = new AbcContext();
	
	public ConfusionTask() {
		super();
		mixWordFactory = new DefaultMixWordFactory() {
			
			@Override
			public void log(String ori, String mix) {
				logMix(ori, mix);
			}
		};
	}
	
	/**
	 * 将混淆的日志打出
	 * @param ori
	 * @param mix
	 */
	private void logMix(String ori, String mix) {
		if (logStream != null) {
			String s = ori + "<<-->>" + mix + "\n";
			try {
				logStream.write(s.getBytes());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void setLogFile(File logFile) {
		this.logFile = logFile;
	}

	@Override
	protected void process() throws BuildException {
		try {
			if (logFile != null) {
				if (!logFile.exists())
					logFile.createNewFile();
				logStream = new FileOutputStream(logFile);
			}
			
			configKeyWordList();
			configMixChar();
			configExcludeLib();
			MovieMixer[] mm = new MovieMixer[allSwf.size()];
			//解析
			for (int i = 0; i < mm.length; i++) {
				Swf swf = allSwf.get(i);
				MovieMixer mixer = new MovieMixer(abcContext,
						new FileInputStream(swf.getInput()));
				mixer.parse();
				mm[i] = mixer;
			}
			//混淆
			for (int i = 0; i < mm.length; i++) {
				MovieMixer movieMixer = mm[i];
				movieMixer.mix();
			}
			//重组输出
			for (int i = 0; i < mm.length; i++) {
				Swf swf = allSwf.get(i);
				MovieMixer movieMixer = mm[i];
				movieMixer.writeTo(new FileOutputStream(swf.getOutput()));
			}
			
			if (logStream != null) {
				logStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void configExcludeLib() throws Exception {
		for (Swf swf : allExcludeLibList) {
			ExcludeLib el = new ExcludeLib(new FileInputStream(swf.getInput()));
			el.parse();
			abcContext.merge(el.getAbcContext());
		}
	}

	private void configKeyWordList() throws Exception {
		if (keyWordList != null) {
			BufferedReader br = new BufferedReader(new FileReader(keyWordList));
			String s;
			while ((s = br.readLine()) != null) {
				if (!s.startsWith("//")) {
					StringVo vo = abcContext.getString(s).vo;
					vo.setCanNotMix();
					vo.pushString(true);
				}
			}
		}
	}

	private void configMixChar() throws Exception {
		if (mixCharFile != null) {
			ArrayList<String> list = new ArrayList<String>();
			BufferedReader br = new BufferedReader(new FileReader(mixCharFile));
			String s;
			while ((s = br.readLine()) != null) {
				if (list.indexOf(s) == -1)
					list.add(s);
			}
			mixWordFactory.setList(list.toArray(new String[list.size()]));
			abcContext.setMixWordFactory(mixWordFactory);
		}
	}

	public void addExcludeLib(Swf lib) {
		allExcludeLibList.add(lib);
	}

	public Swf createExcludeLib() {
		return new Swf();
	}

	public void addSwf(Swf swf) {
		allSwf.add(swf);
	}

	public Swf createSwf() {
		return new Swf();
	}

	public String getKeyWordList() {
		return keyWordList;
	}

	public void setKeyWordList(String keyWordList) {
		this.keyWordList = keyWordList;
	}

	public String getMixCharFile() {
		return mixCharFile;
	}

	public void setMixCharFile(String mixCharFile) {
		this.mixCharFile = mixCharFile;
	}
}